package sfin.swt.component;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.joda.time.DateTimeFieldType;
import org.joda.time.YearMonth;

import sfin.swt.component.event.YearMonthChangeEvent;
import sfin.swt.component.event.YearMonthChangeListener;
import sfin.swt.util.ResourceUtil;

public class YearMonthComposite extends Composite{
	
	private Combo yearCombo;
	private Combo monthCombo;
	private YearMonth yearMonth = YearMonth.now();

	private List<YearMonthChangeListener> listeners = new ArrayList<YearMonthChangeListener>();
	
	public void next(){
		yearMonth = yearMonth.plusMonths(1);
		updateComponent();
	}

	public void previous(){
		yearMonth = yearMonth.minusMonths(1);
		updateComponent();
	}
	
	public void goMonth(int month){
		yearMonth = yearMonth.withMonthOfYear(month);
		updateComponent();
	}
	
	public void goYear(int year){
		yearMonth = yearMonth.withYear(year);
		updateComponent();
	}
	
	public YearMonthComposite(Composite parent, int style) {
		super(parent, style);
		initialize();
	}
	
	public int getCurrentYear(){
		return yearMonth.get(DateTimeFieldType.year());
	}
	
	public int getCurrentMonth(){
		return yearMonth.get(DateTimeFieldType.monthOfYear());
	}
	
	private void updateComponent(){
		int index = yearCombo.indexOf(String.valueOf(getCurrentYear()));
		yearCombo.select(index);
		monthCombo.select(getCurrentMonth()-1);
		notifyListeners();
	}
	
	private void updateData(){
		int month = monthCombo.getSelectionIndex();
		int year = Integer.parseInt( yearCombo.getItem( yearCombo.getSelectionIndex() ) );
		yearMonth = new YearMonth(year, month);
		notifyListeners();
	}

	private void initialize(){
		
		setLayout(new RowLayout(SWT.HORIZONTAL));
		Display display = getDisplay();
		
		Button button = new Button(this, SWT.PUSH);
		button.setImage(ResourceUtil.getImage(display, "date-previous-icon.png"));
		button.setLayoutData(new RowData());
		button.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				previous();
			}
		});
		
		monthCombo = new Combo(this, SWT.NONE | SWT.READ_ONLY);
		monthCombo.setLayoutData(new RowData());
		monthCombo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				updateData();
			}
		});
		
		new Label(this,SWT.SEPARATOR | SWT.VERTICAL).setLayoutData(new RowData());
		
		yearCombo = new Combo(this, SWT.NONE | SWT.READ_ONLY);
		yearCombo.setLayoutData(new RowData());
		yearCombo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				updateData();
			}
		});
		
		button = new Button(this, SWT.PUSH);
		button.setImage(ResourceUtil.getImage(display, "date-next-icon.png"));
		button.setLayoutData(new RowData());
		button.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				next();
			}
		});
		
	}
	
	
	public void addPeriodChangedListener(YearMonthChangeListener listener){
		if(!listeners.contains(listener)){
			listeners.add(listener);
		}
	}
	
	private YearMonthChangeEvent createChangedEvent(){
		YearMonthChangeEvent evt = new YearMonthChangeEvent();
		evt.year = yearMonth.get(DateTimeFieldType.year());
		evt.month = yearMonth.get(DateTimeFieldType.monthOfYear());
		return evt;
	}

	private boolean isValidState(){
		return true;
	}
	
	private void notifyListeners(){
		
		if(!isValidState())
			return;
		
		YearMonthChangeEvent evt = createChangedEvent();
		for(int i = 0; i<listeners.size(); i++){
			listeners.get(i).periodChanged(evt);
		}
		
	}
	
	public void setYears(List<String> years){
		yearCombo.setItems(years.toArray(new String[]{}));
	}
	
	public void setMonths(List<String> months){
		monthCombo.setItems(months.toArray(new String[]{}));
	}
	
}